#include <gtest/gtest.h>

#ifndef private
#define private public
#include "acl/acl.h"
#include "log_inner.h"
#include "runtime/rt.h"
#include "runtime/rts/rts.h"
#undef private
#endif

class UTEST_ACL_compatibility_cast_check : public testing::Test
{
    public:
        UTEST_ACL_compatibility_cast_check() {}

    protected:
        virtual void SetUp() {}
        virtual void TearDown() {}
};

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtBinaryLoadOptionType)
{
    EXPECT_EQ((uint64_t)ACL_RT_BINARY_LOAD_OPT_LAZY_LOAD, (uint64_t)RT_LOAD_BINARY_OPT_LAZY_LOAD);
    EXPECT_EQ((uint64_t)ACL_RT_BINARY_LOAD_OPT_LAZY_MAGIC, (uint64_t)RT_LOAD_BINARY_OPT_MAGIC);

    EXPECT_EQ(sizeof(aclrtBinaryLoadOptionType), sizeof(rtLoadBinaryOption));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtLaunchKernelAttrId)
{
    EXPECT_EQ((uint64_t)ACL_RT_LAUNCH_KERNEL_ATTR_SCHEM_MODE, (uint64_t)RT_LAUNCH_KERNEL_ATTR_SCHEM_MODE);

    EXPECT_EQ(sizeof(aclrtLaunchKernelAttrId), sizeof(rtLaunchKernelAttrId));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMemcpyKind)
{
    EXPECT_EQ((uint64_t)ACL_MEMCPY_HOST_TO_HOST, (uint64_t)RT_MEMCPY_KIND_HOST_TO_HOST);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_HOST_TO_DEVICE, (uint64_t)RT_MEMCPY_KIND_HOST_TO_DEVICE);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_DEVICE_TO_HOST, (uint64_t)RT_MEMCPY_KIND_DEVICE_TO_HOST);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_DEVICE_TO_DEVICE, (uint64_t)RT_MEMCPY_KIND_DEVICE_TO_DEVICE);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_DEFAULT, (uint64_t)RT_MEMCPY_KIND_DEFAULT);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_HOST_TO_BUF_TO_DEVICE, (uint64_t)RT_MEMCPY_KIND_HOST_TO_BUF_TO_DEVICE);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_INNER_DEVICE_TO_DEVICE, (uint64_t)RT_MEMCPY_KIND_INNER_DEVICE_TO_DEVICE);
    EXPECT_EQ((uint64_t)ACL_MEMCPY_INTER_DEVICE_TO_DEVICE, (uint64_t)RT_MEMCPY_KIND_INTER_DEVICE_TO_DEVICE);

    EXPECT_EQ(sizeof(aclrtMemcpyKind), sizeof(rtMemcpyKind));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtBinaryLoadOption)
{
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtBinaryLoadOption, type), OFFSET_OF_MEMBER(rtLoadBinaryOption_t , optionId));
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtBinaryLoadOption, value), OFFSET_OF_MEMBER(rtLoadBinaryOption_t, value));

    EXPECT_EQ(sizeof(aclrtBinaryLoadOption), sizeof(rtLoadBinaryOption_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtBinaryLoadOptions)
{
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtBinaryLoadOptions, options), OFFSET_OF_MEMBER(rtLoadBinaryConfig_t, options));
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtBinaryLoadOptions, numOpt), OFFSET_OF_MEMBER(rtLoadBinaryConfig_t, numOpt));

    EXPECT_EQ(sizeof(aclrtBinaryLoadOptions), sizeof(rtLoadBinaryConfig_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtLaunchKernelAttr)
{
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtLaunchKernelAttr, id), OFFSET_OF_MEMBER(rtLaunchKernelAttr_t , id));
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtLaunchKernelAttr, value), OFFSET_OF_MEMBER(rtLaunchKernelAttr_t, value));

    EXPECT_EQ(sizeof(aclrtLaunchKernelAttr), sizeof(rtLaunchKernelAttr_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtLaunchKernelCfg)
{
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtLaunchKernelCfg, attrs), OFFSET_OF_MEMBER(rtKernelLaunchCfg_t , attrs));
    EXPECT_EQ(OFFSET_OF_MEMBER(aclrtLaunchKernelCfg, numAttrs), OFFSET_OF_MEMBER(rtKernelLaunchCfg_t, numAttrs));

    EXPECT_EQ(sizeof(aclrtLaunchKernelCfg), sizeof(rtKernelLaunchCfg_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtBinaryLoadOptionValue)
{
    size_t aclAlign = alignof(decltype(aclrtBinaryLoadOptionValue::isLazyLoad));
    EXPECT_EQ(aclAlign, alignof(decltype(rtLoadBinaryOptionValue_t::isLazyLoad)));

    EXPECT_EQ(sizeof(aclrtBinaryLoadOptionValue), sizeof(rtLoadBinaryOptionValue_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtLaunchKernelAttrValue)
{
    size_t aclAlign = alignof(decltype(aclrtLaunchKernelAttrValue::schemMode));
    EXPECT_EQ(aclAlign, alignof(decltype(rtLaunchKernelAttrVal_t::schemMode)));
    EXPECT_EQ(sizeof(aclrtLaunchKernelAttrValue), sizeof(rtLaunchKernelAttrVal_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMemMallocPolicy)
{
    EXPECT_EQ((uint64_t)ACL_MEM_MALLOC_HUGE_FIRST, (uint64_t)RT_MEM_MALLOC_HUGE_FIRST);
    EXPECT_EQ((uint64_t)ACL_MEM_MALLOC_HUGE_ONLY, (uint64_t)RT_MEM_MALLOC_HUGE_ONLY);
    EXPECT_EQ((uint64_t)ACL_MEM_MALLOC_NORMAL_ONLY, (uint64_t)RT_MEM_MALLOC_NORMAL_ONLY);
    EXPECT_EQ((uint64_t)ACL_MEM_MALLOC_HUGE_FIRST_P2P, (uint64_t)RT_MEM_MALLOC_HUGE_FIRST_P2P);
    EXPECT_EQ((uint64_t)ACL_MEM_MALLOC_HUGE_ONLY_P2P, (uint64_t)RT_MEM_MALLOC_HUGE_ONLY_P2P);
    EXPECT_EQ((uint64_t)ACL_MEM_MALLOC_NORMAL_ONLY_P2P, (uint64_t)RT_MEM_MALLOC_NORMAL_ONLY_P2P);
    EXPECT_EQ((uint64_t)ACL_MEM_TYPE_LOW_BAND_WIDTH, (uint64_t)RT_MEM_TYPE_LOW_BAND_WIDTH);
    EXPECT_EQ((uint64_t)ACL_MEM_TYPE_HIGH_BAND_WIDTH, (uint64_t)RT_MEM_TYPE_HIGH_BAND_WIDTH);
    EXPECT_EQ((uint64_t)ACL_MEM_ACCESS_USER_SPACE_READONLY, (uint64_t)RT_MEM_ACCESS_USER_SPACE_READONLY);

    // check total size
    EXPECT_EQ(sizeof(aclrtMemMallocPolicy), sizeof(rtMallocPolicy));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtHostRegisterType)
{
    EXPECT_EQ((uint64_t)ACL_HOST_REGISTER_MAPPED, (uint64_t)RT_HOST_REGISTER_MAPPED);

    // check total size
    EXPECT_EQ(sizeof(aclrtHostRegisterType), sizeof(rtHostRegisterType));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMallocAttrType)
{
    EXPECT_EQ((uint64_t)ACL_RT_MEM_ATTR_RSV, (uint64_t)RT_MEM_MALLOC_ATTR_RSV);
    EXPECT_EQ((uint64_t)ACL_RT_MEM_ATTR_MODULE_ID, (uint64_t)RT_MEM_MALLOC_ATTR_MODULE_ID);
    EXPECT_EQ((uint64_t)ACL_RT_MEM_ATTR_DEVICE_ID, (uint64_t)RT_MEM_MALLOC_ATTR_DEVICE_ID);

    // check total size
    EXPECT_EQ(sizeof(aclrtMallocAttrType), sizeof(rtMallocAttr));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtCmoType)
{
    EXPECT_EQ((uint64_t)ACL_RT_CMO_TYPE_PREFETCH + 6UL, (uint64_t)RT_CMO_PREFETCH);
    EXPECT_EQ((uint64_t)ACL_RT_CMO_TYPE_WRITEBACK + 6UL, (uint64_t)RT_CMO_WRITEBACK);
    EXPECT_EQ((uint64_t)ACL_RT_CMO_TYPE_INVALID + 6UL, (uint64_t)RT_CMO_INVALID);
    EXPECT_EQ((uint64_t)ACL_RT_CMO_TYPE_FLUSH + 6UL, (uint64_t)RT_CMO_FLUSH);

    // check total size
    EXPECT_EQ(sizeof(aclrtCmoType), sizeof(rtCmoOpCode_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMallocAttrValue)
{
    // check total size
    EXPECT_EQ(sizeof(aclrtMallocAttrValue), sizeof(rtMallocAttrValue));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMallocAttribute)
{
    size_t acl_offset, rts_offset;
    acl_offset = OFFSET_OF_MEMBER(aclrtMallocAttribute, attr);
    rts_offset = OFFSET_OF_MEMBER(rtMallocAttribute_t, attr);
    EXPECT_EQ(acl_offset, rts_offset);

    acl_offset = OFFSET_OF_MEMBER(aclrtMallocAttribute, value);
    rts_offset = OFFSET_OF_MEMBER(rtMallocAttribute_t, value);
    EXPECT_EQ(acl_offset, rts_offset);

    // check total size
    EXPECT_EQ(sizeof(aclrtMallocAttribute), sizeof(rtMallocAttribute_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMallocConfig)
{
    size_t acl_offset, rts_offset;
    acl_offset = OFFSET_OF_MEMBER(aclrtMallocConfig, attrs);
    rts_offset = OFFSET_OF_MEMBER(rtMallocConfig_t, attrs);
    EXPECT_EQ(acl_offset, rts_offset);

    acl_offset = OFFSET_OF_MEMBER(aclrtMallocConfig, numAttrs);
    rts_offset = OFFSET_OF_MEMBER(rtMallocConfig_t, numAttrs);
    EXPECT_EQ(acl_offset, rts_offset);

    // check total size
    EXPECT_EQ(sizeof(aclrtMallocConfig), sizeof(rtMallocConfig_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtMemLocation)
{
    size_t acl_offset, rts_offset;
    acl_offset = OFFSET_OF_MEMBER(aclrtMemLocation, id);
    rts_offset = OFFSET_OF_MEMBER(rtMemLocation, id);
    EXPECT_EQ(acl_offset, rts_offset);

    acl_offset = OFFSET_OF_MEMBER(aclrtMemLocation, type);
    rts_offset = OFFSET_OF_MEMBER(rtMemLocation, type);
    EXPECT_EQ(acl_offset, rts_offset);

    // check total size
    EXPECT_EQ(sizeof(aclrtMemLocation), sizeof(rtMemLocation));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtPtrAttributes)
{
    size_t acl_offset, rts_offset;
    acl_offset = OFFSET_OF_MEMBER(aclrtPtrAttributes, location);
    rts_offset = OFFSET_OF_MEMBER(rtPtrAttributes_t, location);
    EXPECT_EQ(acl_offset, rts_offset);

    acl_offset = OFFSET_OF_MEMBER(aclrtPtrAttributes, pageSize);
    rts_offset = OFFSET_OF_MEMBER(rtPtrAttributes_t, pageSize);
    EXPECT_EQ(acl_offset, rts_offset);

    acl_offset = OFFSET_OF_MEMBER(aclrtPtrAttributes, rsv);
    rts_offset = OFFSET_OF_MEMBER(rtPtrAttributes_t, rsv);
    EXPECT_EQ(acl_offset, rts_offset);

    // check total size
    EXPECT_EQ(sizeof(aclrtPtrAttributes), sizeof(rtPtrAttributes_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtStreamAttrValue)
{
    // check total size
    EXPECT_EQ(sizeof(aclrtStreamAttrValue), sizeof(rtStreamAttrValue_t));
}

TEST_F(UTEST_ACL_compatibility_cast_check, model_stream_flag)
{
    EXPECT_EQ((uint64_t)ACL_MODEL_STREAM_FLAG_HEAD, (uint64_t)RT_MODEL_STREAM_FLAG_HEAD);
    EXPECT_EQ((uint64_t)ACL_MODEL_STREAM_FLAG_DEFAULT, (uint64_t)RT_MODEL_STREAM_FLAG_DEFAULT);
}

TEST_F(UTEST_ACL_compatibility_cast_check, device_get_capability_flags)
{
    EXPECT_EQ((uint64_t)ACL_DEV_FEATURE_SUPPORT, (uint64_t)FEATURE_SUPPORT);
    EXPECT_EQ((uint64_t)ACL_DEV_FEATURE_NOT_SUPPORT, (uint64_t)FEATURE_NOT_SUPPORT);
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtStreamAttr)
{
    EXPECT_EQ((uint64_t)ACL_STREAM_ATTR_FAILURE_MODE, (uint64_t)RT_STREAM_ATTR_FAILURE_MODE);
    EXPECT_EQ((uint64_t)ACL_STREAM_ATTR_FLOAT_OVERFLOW_CHECK, (uint64_t)RT_STREAM_ATTR_FLOAT_OVERFLOW_CHECK);
    EXPECT_EQ((uint64_t)ACL_STREAM_ATTR_USER_CUSTOM_TAG, (uint64_t)RT_STREAM_ATTR_USER_CUSTOM_TAG);

    // check total size
    EXPECT_EQ(sizeof(aclrtStreamAttr), sizeof(rtStreamAttr));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtDevAttr)
{
    EXPECT_EQ((uint64_t)ACL_DEV_ATTR_AICPU_CORE_NUM, (uint64_t)RT_DEV_ATTR_AICPU_CORE_NUM);
    EXPECT_EQ((uint64_t)ACL_DEV_ATTR_AICORE_CORE_NUM, (uint64_t)RT_DEV_ATTR_AICORE_CORE_NUM);
    EXPECT_EQ((uint64_t)ACL_DEV_ATTR_VECTOR_CORE_NUM, (uint64_t)RT_DEV_ATTR_VECTOR_CORE_NUM);

    // check total size
    EXPECT_EQ(sizeof(aclrtDevAttr), sizeof(rtDevAttr));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtDevFeatureType)
{
    EXPECT_EQ((uint64_t)ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV, (uint64_t)RT_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV);
    EXPECT_EQ((uint64_t)ACL_FEATURE_SYSTEM_MEMQ_EVENT_CRORSS_DEV, (uint64_t)RT_FEATURE_SYSTEM_MEMQ_EVENT_CRORSS_DEV);

    // check total size
    EXPECT_EQ(sizeof(aclrtDevFeatureType), sizeof(rtDevFeatureType));
}

TEST_F(UTEST_ACL_compatibility_cast_check, aclrtReduceKind)
{
    EXPECT_EQ((uint64_t)ACL_RT_MEMCPY_SDMA_AUTOMATIC_SUM, (uint64_t)RT_MEMCPY_SDMA_AUTOMATIC_ADD);
    EXPECT_EQ((uint64_t)ACL_RT_MEMCPY_SDMA_AUTOMATIC_MAX, (uint64_t)RT_MEMCPY_SDMA_AUTOMATIC_MAX);
    EXPECT_EQ((uint64_t)ACL_RT_MEMCPY_SDMA_AUTOMATIC_MIN, (uint64_t)RT_MEMCPY_SDMA_AUTOMATIC_MIN);
    EXPECT_EQ((uint64_t)ACL_RT_MEMCPY_SDMA_AUTOMATIC_EQUAL, (uint64_t)RT_MEMCPY_SDMA_AUTOMATIC_EQUAL);

    // check total size
    EXPECT_EQ(sizeof(aclrtReduceKind), sizeof(rtReduceKind));
}
